#include "task-queue.h"

// #define DEBUG_PROGRAM

Node *createNode(Task *task, Node *next);       // 创建节点

void destroyNode(Node *node);                   // 销毁节点

struct TaskQueue {
    int size;

    int capacity;

    Node *header;

    Node *tail;
};

struct Node {
    Task *task;

    Node *next;
};

TaskQueue *createTaskQueue(int capacity) {
    TaskQueue *queue = (TaskQueue *) malloc(sizeof(TaskQueue));
    if (queue == NULL) {
# ifdef DEBUG_PROGRAM
        printf("Task Queue Apply Form Memory Fail!\n");
# endif
        return NULL;
    }

    queue->size = 0;
    queue->capacity = capacity;
    queue->header = NULL;
    queue->tail = NULL;

# ifdef DEBUG_PROGRAM
    printf("Task Queue Create Success!\n");
# endif
    return queue;
}

void destroyTaskQueue(TaskQueue *queue) {
    clear(queue);

    free(queue);
    queue = NULL;

# ifdef DEBUG_PROGRAM
    printf("Task Queue Destroy Success!\n");
# endif
}

int size(TaskQueue *queue) {
    return queue->size;
}

int capacity(TaskQueue *queue) {
    return queue->capacity;
}

bool empty(TaskQueue *queue) {
    return queue->header == NULL;
}

Task *front(TaskQueue *queue) {
    if (queue->header != NULL) {
        return queue->header->task;
    }

# ifdef DEBUG_PROGRAM
    printf("Front Operation Fail, Task Queue Front Is Empty!\n");
# endif
    return NULL;
}

Task *back(TaskQueue *queue) {
    if (queue->tail != NULL) {
        return queue->tail->task;
    }

# ifdef DEBUG_PROGRAM
    printf("Front Operation Fail, Task queue Front Is Empty!\n");
# endif
    return NULL;
}

void clear(TaskQueue *queue) {
    Node *p = queue->header;
    while (p != NULL) {
        Node *temp = p;
        p = p->next;

        destroyNode(temp);
        temp = NULL;
    }

    queue->size = 0;
    queue->header = NULL;
    queue->tail = NULL;
}

bool push(TaskQueue *queue, Task *task) {
    if (queue->size == queue->capacity) {
# ifdef DEBUG_PROGRAM
        printf("Task Queue Is Full, Push Operation Fail!\n");
# endif
        return false;
    }

    Node *node = createNode(task, NULL);
    if (queue->header == NULL) {
        queue->header = queue->tail = node;

    } else {
        queue->tail->next = node;
        queue->tail = node;
    }
    queue->size++;

    return true;
}

bool pop(TaskQueue *queue) {
    if (empty(queue)) {
# ifdef DEBUG_PROGRAM
        printf("Task Queue Is Empty, Pop Operation Fail!\n");
# endif
        return false;
    }

    Node *temp = queue->header;
    queue->header = queue->header->next;
    queue->size--;

    destroyNode(temp);

    return true;
}

Node *createNode(Task *task, Node *next) {
    Node *node = malloc(sizeof(Node));

    if (node == NULL) {
# ifdef DEBUG_PROGRAM
        printf("Node Apply Form Memory Fail!\n");
# endif
        return NULL;
    }

    node->task = task;
    node->next = next;

# ifdef DEBUG_PROGRAM
    // printf("Create Node Success!\n");
# endif
    return node;
}

// 销毁节点时不处理节点附带的任务(让线程池处理未完成的任务)
void destroyNode(Node *node) {
    node->task = NULL;
    node->next = NULL;

    free(node);
    node = NULL;

# ifdef DEBUG_PROGRAM
    // printf("Destroy Node Success!\n");
# endif
}